﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="Keyboard.cs" company="Marek Dzikiewicz">
//   Marek Dzikiewicz, All Rights Reserved.
// </copyright>
// --------------------------------------------------------------------------------------------------------------------

namespace Dzikiewicz.WinApi.User.Keyboard
{
    using System;
    using System.ComponentModel;
    using System.Runtime.InteropServices;
    using System.Threading;
    using System.Windows.Forms;
    using Dzikiewicz.WinApi.Kernel.Data;

    /// <summary>
    /// Implements methods for keyboard and hotkey management.
    /// </summary>
    public static class Keyboard
    {
        /// <summary>
        /// Registers the specified global hot key for the specified window handle.
        /// </summary>
        /// <param name="handle">The handle of the window for which the hot key will be registered.</param>
        /// <param name="name">The name of the hot key.</param>
        /// <param name="keys">The hot key to register.</param>
        /// <param name="modifiers">The modifiers of the hot key to register.</param>
        /// <returns>The identifier of the registered hot key.</returns>
        /// <exception cref="Win32Exception">
        /// A WINAPI error occurred while registering the specified hot key.
        /// </exception>
        public static short RegisterHotKey(IntPtr handle, string name, Keys keys, KeyModifiers modifiers)
        {
            // Generate hot key atom name.
            int threadId = Thread.CurrentThread.ManagedThreadId;
            string atomName = threadId.ToString("X8") + name;

            // Generate hot key atom.
            short hotKeyAtom = AtomApi.GlobalAddAtom(atomName);
            if (hotKeyAtom == 0)
            {
                throw new Win32Exception(Marshal.GetLastWin32Error());
            }

            // Register hot key.
            if (KeyboardApi.RegisterHotKey(handle, hotKeyAtom, (int)modifiers, (int)keys) == 0)
            {
                AtomApi.GlobalDeleteAtom(hotKeyAtom);
                throw new Win32Exception(Marshal.GetLastWin32Error());
            }

            return hotKeyAtom;   
        }

        /// <summary>
        /// Unregisters the specified global hot key for the specified window handle.
        /// </summary>
        /// <param name="handle">
        /// The handle of the window for which the hot key will be unregistered.
        /// </param>
        /// <param name="hotKeyAtomId">The identifier of the hot key to unregister.</param>
        public static void UnregisterHotKey(IntPtr handle, short hotKeyAtomId)
        {
            KeyboardApi.UnregisterHotKey(handle, hotKeyAtomId);
            AtomApi.GlobalDeleteAtom(hotKeyAtomId);
        }
    }
}